package com.jinyongjie.mediaplayer_demo;

import android.annotation.TargetApi;
import android.media.MediaPlayer;
import android.media.TimedMetaData;
import android.media.TimedText;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import java.io.IOException;

@TargetApi(Build.VERSION_CODES.M)
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public class MainActivity extends AppCompatActivity implements MediaPlayer.OnBufferingUpdateListener,
MediaPlayer.OnCompletionListener,
MediaPlayer.OnErrorListener,
MediaPlayer.OnInfoListener,
MediaPlayer.OnPreparedListener,
MediaPlayer.OnSeekCompleteListener,
MediaPlayer.OnVideoSizeChangedListener,
MediaPlayer.OnTimedTextListener,
MediaPlayer.OnTimedMetaDataAvailableListener,
        View.OnClickListener,
        SeekBar.OnSeekBarChangeListener,
        SurfaceHolder.Callback{
enum player_state{
    state_idle,
    state_preparing,
    state_prepared,
    state_playing,
    state_paused,
    state_complete,
    state_stop,
    state_end,
    state_err
}
    private static final String TAG = "tag_mediaplayer";

    private FrameLayout mSurfaceContainer;
    private SurfaceView mSurfaceView;
    private Button mButtonPlay;
    private Button mButtonPause;
    private Button mButtonStop;
    private Button mButtonReset;
    private Button mButtonRelease;
    private Button mButtonCreateSurface;
    private Button mButtonDestroySurface;
    private SeekBar mSeekbar;
    private EditText mEditUrl;
    private TextView mTextCurrentTime;
    private TextView mTextDuration;
    private TextView mTextState;
    private TextView mTextErr;
    private MediaPlayer mMediaPlayer;
    private player_state mState = player_state.state_idle;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mSurfaceContainer = (FrameLayout) findViewById(R.id.surface_container);
        mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
        mButtonPlay = (Button) findViewById(R.id.button_play);
        mButtonPause = (Button) findViewById(R.id.button_pause);
        mButtonStop = (Button) findViewById(R.id.button_stop);
        mButtonReset = (Button) findViewById(R.id.button_reset);
        mButtonRelease = (Button) findViewById(R.id.button_release);
        mButtonCreateSurface = (Button) findViewById(R.id.button_create_surface);
        mButtonDestroySurface = (Button) findViewById(R.id.button_destroy_surface);
        mSeekbar = (SeekBar) findViewById(R.id.seekbar);
        mEditUrl = (EditText) findViewById(R.id.edit_url);
        mTextState = (TextView) findViewById(R.id.text_state);
        mTextErr = (TextView) findViewById(R.id.text_err);
        mTextCurrentTime = (TextView) findViewById(R.id.text_current_time);
        mTextDuration = (TextView) findViewById(R.id.text_duration);

        mSurfaceView.getHolder().addCallback(this);
        mSeekbar.setOnSeekBarChangeListener(this);
        mButtonPause.setOnClickListener(this);
        mButtonPlay.setOnClickListener(this);
        mButtonStop.setOnClickListener(this);
        mButtonReset.setOnClickListener(this);
        mButtonRelease.setOnClickListener(this);
        mButtonCreateSurface.setOnClickListener(this);
        mButtonDestroySurface.setOnClickListener(this);

        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnPreparedListener(this);
        mMediaPlayer.setOnBufferingUpdateListener(this);
        mMediaPlayer.setOnErrorListener(this);
        mMediaPlayer.setOnCompletionListener(this);
        mMediaPlayer.setOnInfoListener(this);
        mMediaPlayer.setOnSeekCompleteListener(this);
        mMediaPlayer.setOnVideoSizeChangedListener(this);
        mMediaPlayer.setOnTimedMetaDataAvailableListener(this);
        mMediaPlayer.setOnTimedTextListener(this);

        setState(player_state.state_idle);
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) {
        Log.v(TAG,"onBufferingUpdate" + percent);
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        Log.d(TAG,"onCompletion");
        setState(player_state.state_complete);
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        Log.d(TAG,"onError what=" + what + " extra="+extra);
        setState(player_state.state_err);
        mTextErr.setText("err what="+what + " extra="+extra);
        return false;
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) {
        Log.v(TAG,"onInfo what=" + what + " extra="+extra);
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        Log.d(TAG,"onPrepared");
        setState(player_state.state_prepared);
        mMediaPlayer.start();
        setState(player_state.state_playing);
    }

    @Override
    public void onSeekComplete(MediaPlayer mp) {
        Log.d(TAG,"onSeekComplete");
    }

    @Override
    public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data) {
        Log.d(TAG,"onTimedMetaDataAvailable " + data);
    }

    @Override
    public void onTimedText(MediaPlayer mp, TimedText text) {
        Log.d(TAG,"onTimeText "+text);
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        Log.d(TAG,"onVideoSizeChanged "+width + " "+height);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId())
        {
            case R.id.button_play:
            {
                onClickPlay();

                break;
            }
            case R.id.button_pause:
            {
                mMediaPlayer.pause();
                setState(player_state.state_paused);

                break;
            }
            case R.id.button_stop:
            {
                mMediaPlayer.stop();
                setState(player_state.state_stop);
                break;
            }
            case R.id.button_reset:
            {
                mMediaPlayer.reset();
                setState(player_state.state_idle);
                break;
            }
            case R.id.button_release:
            {
                mMediaPlayer.release();
                setState(player_state.state_end);
                break;
            }
            case R.id.button_create_surface:
            {
                if(mSurfaceView != null) {
                    mSurfaceContainer.removeView(mSurfaceView);
                }
                mSurfaceView = new SurfaceView(this);
                mSurfaceView.getHolder().addCallback(this);
                mSurfaceContainer.addView(mSurfaceView,FrameLayout.LayoutParams.MATCH_PARENT,
                        FrameLayout.LayoutParams.MATCH_PARENT);
                break;
            }
            case R.id.button_destroy_surface:
            {
                if(mSurfaceView == null)
                    return;
                mSurfaceContainer.removeView(mSurfaceView);
                mSurfaceView = null;
                break;
            }
        }
    }
    private void onClickPlay()
    {
        if(mState == player_state.state_paused||
                mState == player_state.state_prepared)
        {
            mMediaPlayer.start();
            setState(player_state.state_playing);
        }
        else {
            if(mState == player_state.state_idle) {
                try {
                    String url = mEditUrl.getText().toString();
                    mMediaPlayer.setDataSource(url);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            mMediaPlayer.setDisplay(mSurfaceView.getHolder());
            mMediaPlayer.prepareAsync();
            setState(player_state.state_preparing);
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if(!fromUser)
            return;
        if(mState == player_state.state_playing||
                mState == player_state.state_paused) {
            int duration = mMediaPlayer.getDuration();
            mMediaPlayer.seekTo(duration*progress/seekBar.getMax());
        }
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG,"surfaceCreated");
        mMediaPlayer.setDisplay(holder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.d(TAG,"surfaceChanged "+format + " "+width+" " + height);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d(TAG,"surfaceDestroyed");
        //mMediaPlayer.setDisplay(null);
    }

    private void setState(player_state state)
    {
        if(mState == state)
            return;
        mState = state;
        updateView();
    }
    private String state2String(player_state state)
    {
        switch (state)
        {
            case state_idle:
                return "idle";
            case state_preparing:
                return "preparing";
            case state_prepared:
                return "prepared";
            case state_playing:
                return "playing";
            case state_paused:
                return "paused";
            case state_err:
                return "err";
            case state_complete:
                return "complete";
            case state_end:
                return "end";
            case state_stop:
                return "stop";
        }

        return "";
    }
    private void updateView()
    {
        mTextState.setText(state2String(mState));
        if(mState == player_state.state_playing)
        {
            mButtonPause.setVisibility(View.VISIBLE);
            mButtonPlay.setVisibility(View.GONE);
        }
        else
        {
            mButtonPlay.setVisibility(View.VISIBLE);
            mButtonPause.setVisibility(View.GONE);
        }
    }
}
